/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gauss.seidel;

import gauss.seidel.gui.GaussSeidelGUI;
import java.text.DecimalFormat;

/**
 *
 * @author User007
 */
public class GaussSeidel {

    GaussSeidelGUI janela = new GaussSeidelGUI(this);
    DecimalFormat df = new DecimalFormat("0.0000");

    public void resolver(double a[][], double x[][], double b[][], double tolerancia) {

        double e = 0;
        int k = 1;
        boolean convergiu = false;
        double xAnterior[][] = new double[x.length][x[0].length];

        //x = Fx + d

        while (k < 100 && !convergiu) {

            for (int i = 0; i < x[0].length; i++) {
                xAnterior[0][i] = x[0][i];
            }

            System.out.println("K = " + k);

            //i = coluna
            for (int i = 0; i < x[0].length; i++) {

                double somatorio = 0;

                //j = linha
                for (int j = 0; j < x[0].length; j++) {

                    double anm = a[i][j];
                    double ax = anm * x[0][j];

                    //Evita somar ann
                    if (i != j) {
                        somatorio = somatorio + ax;

                    }
                }

                //Encontra valor de xi
                x[0][i] = (b[0][i] - (somatorio)) / a[i][i];
                System.out.println("x" + (i + 1) + " = " + df.format(x[0][i]));
            }
            
            

            //Verifica se convergiu
            e = convergiu(x, xAnterior);
            janela.imprimirVetor(x, k, e);
            System.out.println("e: " + df.format(e));
            if (e < tolerancia) {
                convergiu = true;
            }
            k++;
        }

        System.out.println("Vetor solução: ");
        for (int i = 0; i < x[0].length; i++) {
            System.out.println("x[" + (i+1) + "] = " + df.format(x[0][i]));
        }
        System.out.println("Número de iterações: " + k);
        System.out.println("Grau de precisão: " + df.format(e));
    }

    public void showInterface()
    {
        janela.setVisible(true);
    }

    private double convergiu(double x[][], double xAnterior[][]) {
        double max = -1;
        double e = -1;

        for (int i = 0; i < x[0].length; i++) {

            e = Math.abs(x[0][i] - xAnterior[0][i]);
            max = Math.max(max, e);

        }

        e = max;

        return e;
    }
}
